/**
 * 
 */
package com.avritech.zapsaude.test.handler.factory;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

import javax.annotation.Resource;

import org.org.usurper.handlers.IHandler;
import org.org.usurper.model.SpecificPropertyDefinition;
import org.springframework.stereotype.Service;

import com.avritech.zapsaude.constraint.CEP;
import com.avritech.zapsaude.constraint.CPForCNPJ;
import com.avritech.zapsaude.constraint.Website;
import com.avritech.zapsaude.model.Availability;
import com.avritech.zapsaude.test.PersistentObjectPropertyHandler;

import coop.tecso.core.persistence.model.PersistentObject;
import coop.tecso.core.test.handlers.ZapSaudeHandlers;
import coop.tecso.core.test.handlers.factory.PropertyHandlerFactory;
import coop.tecso.core.test.handlers.factory.impl.ZapSaudeGeneralHandlerFactory;
import coop.tecso.core.test.utils.SpringContextHelper;

/**
 * @author daniel
 *
 */
@Service("zapSaudePropertyHandlerFactory")
public class ZapSaudePropertyHandlerFactory implements PropertyHandlerFactory {

    private PropertyHandlerFactory generalCaseFactory;

    @Resource(name = "defaultPropertyHandlerFactory")
    private PropertyHandlerFactory delegateFactory;

    @Resource(name = "springContextHelper")
    private SpringContextHelper springContextHelper;

    /**
     * 
     */
    public ZapSaudePropertyHandlerFactory() {
        generalCaseFactory = new ZapSaudeGeneralHandlerFactory();
    }

    /* (non-Javadoc)
     * @see com.avritech.zapsaude.factory.PropertyHandlerFactory#build(java.lang.Class, java.lang.String)
     */
    @Override
    public IHandler build(Class<?> contextualClass, PropertyDescriptor descriptor) {
        Class<?> propertyClass = descriptor.getPropertyType();
        String propertyName = descriptor.getName();
        Method readMethod = descriptor.getReadMethod();
        IHandler generalCase = generalCaseFactory.build(contextualClass, descriptor);
        if (generalCase != null) {
            return generalCase;
        }
        if (readMethod.getAnnotation(CPForCNPJ.class) != null) {
            return new ZapSaudeHandlers.AutocalculatedVerificationCodeHandler(new SpecificPropertyDefinition(contextualClass, propertyName));
        }
        if (propertyName.equals("slotDuration") && contextualClass.equals(Availability.class)) {
            return new ZapSaudeHandlers.RandomMultipleHandler(new SpecificPropertyDefinition(contextualClass, propertyName), 5, 5);
        }
        if (readMethod.getAnnotation(CEP.class) != null) {
            return new ZapSaudeHandlers.NumericStringHandler(new SpecificPropertyDefinition(contextualClass, propertyName), 8);
        }
        if (readMethod.getAnnotation(Website.class) != null) {
            return new ZapSaudeHandlers.DomainHandler(new SpecificPropertyDefinition(contextualClass, propertyName));
        }
        if (PersistentObject.class.isAssignableFrom(propertyClass)) {
            return (PersistentObjectPropertyHandler) springContextHelper.getApplicationContext().getBean("persistentObjectPropertyHandler",
                    (Object) propertyClass);
        }
        return delegateFactory.build(contextualClass, descriptor);
    }
}
